/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package flp.gui.view.genetic;

import flp.solvers.IOptimizationMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 * @author Necro
 * 
 * Klasa nasluchujaca, odpowiedzialna za pobieranie aktualnych danych podczas
 * trwania optymalizacji a nastepnie zaznaczanie ich w odpowiednich strukturach.
 */
public class GeneticOptimizationListener extends Thread implements IOptimizationMonitor {

    /** Kwant czasu o jaki odlegle sa od siebie momenty zaznaczania zebranych danych. */
    public static final int TIMESTEP = 100;
    
    /** Handler ktory stworzyl ta instancje monitora. */
    GeneticSolverHandler parent;
    
    /** Timer obslugujacy zaznaczanie danych. */
    private Timer timer;
    
    /** Licznik iteracji. */
    private int iter;
    
    /**
     * Numer aktualnego cyklu algorytmu.
     */
    private int total;
    
    /** Suma najlepszych kosztow miedzy wyswietleniami.*/
    private int topCostSum;
    
    /** Suma srednich kosztow miedzy wyswietleniami.*/
    private int avgCostSum;
    
    /** Ilosc iteracji miedzy wyswietleniami */
    private int n;
    
    /** Czas jaki uplynal od poczatku obliczen - do zaznaczenia na osi x */
    private int timeElapsed;
    
    /** Flaga sygnalizujaca rozpoczecie optymalizacji */
    private boolean started;

     /** Konstruktor listenera.
     * 
     * @param parent Handler dla obslugiwanej optymalizacji.
     */
    public GeneticOptimizationListener(GeneticSolverHandler parent) {
        this.parent = parent;
        this.started = false;
    }

     /**
     * Klasa odpowiedzialna za pobieranie danych
     * co okreslony kwant czasu.
     */
    class TimeredDataCollector implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            if (n == 0) {
                return;
            }
            timeElapsed += TIMESTEP;
            parent.getDataPanel().updateValues(iter, topCostSum / n, avgCostSum / n, total);
            parent.getChart().markData(topCostSum / n, avgCostSum / n, timeElapsed);
            n = 0;
            topCostSum = 0;
            avgCostSum = 0;


            if (parent.finished) {
                timer.stop();
            }
        }
    }

    @Override
    public void run() {
        timer = new Timer(TIMESTEP, new TimeredDataCollector());
        timer.setDelay(TIMESTEP);
        timer.start();
    }

    
     /** 
     * Metoda wywolywana z ciala Solver.computeSolution
     * zbierajaca dane z kazdej iteracji by je potem wyswietlic na wykresie.
     */
    public void markProgress(Object[] values) {
        iter = (Integer) values[0];
        topCostSum += (Integer) values[1];
        avgCostSum += (Integer) values[2];
        total = (values.length >= 5)
                ? (Integer)values[4]
                : 1;
        
        n++;
    }

    /** 
     * Metoda wywolywana z ciala Solver.computeSolution
     * zbierajaca dane z kazdej iteracji by je potem wyswietlic na wykresie.
     * @deprecated Tylko dla potrzeb testowania.
     */
    public void markProgress(String bestCost) {
         //do_nothing
    }
}
